package com.tianhua.javs.core.parse;

import com.google.common.collect.Lists;
import com.tianhua.javs.client.bean.JavsParamBean;
import com.tianhua.javs.client.bean.JavsScriptMethodBean;
import com.tianhua.javs.client.bean.JavsTranslateContextBean;
import com.tianhua.javs.client.model.MethodModel;
import com.tianhua.javs.client.utils.StringHandleUtils;
import com.tianhua.javs.core.factory.JavsScriptFactory;
import com.tianhua.javs.core.constant.TagConstants;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * Description:javs文件内容字符串解析服务
 * date: 2022/2/10
 *
 * @author shenshuai
 * @version 1.0.0
 * @since JDK 1.8
 */
@Service
public class JavsContentParseService {

    @Autowired
    private JavsScriptFactory javsScriptFactory;

    /**
     * 将一个javs脚本文件转换成javs脚本内容模型
     * @param className 要解析的服务类名
     * @param javsShellFileContentList
     * @return
     */
    public List<JavsScriptMethodBean>  parseContent(JavsTranslateContextBean javsTranslateContextBean, String className, List<String> javsShellFileContentList){
        List<JavsScriptMethodBean> javsScriptMethodBeanList = new ArrayList<>();
        List<String> methodContentList = new ArrayList<>();

        List<String> funcContentList = this.getFuncRowLine(javsShellFileContentList);
        if(CollectionUtils.isEmpty(funcContentList)){
            return javsScriptMethodBeanList;
        }

        for (String shellContent : funcContentList){
            if(StringUtils.isEmpty(shellContent)){
                continue;
            }
            methodContentList.add(shellContent);
            if(shellContent.startsWith("}")){
                JavsScriptMethodBean javsShellContentBean = parseMethod(javsTranslateContextBean, className, methodContentList);
                javsScriptMethodBeanList.add(javsShellContentBean);
                methodContentList.clear();
            }
        }
        return javsScriptMethodBeanList;
    }

    /**
     * 将javs脚本中的函数与Java原生业务函数对应
     * @param javsTranslateContextBean
     * @param className
     * @param methodContentList
     * @return
     */
    private JavsScriptMethodBean parseMethod(JavsTranslateContextBean javsTranslateContextBean, String className, List<String> methodContentList){
        JavsScriptMethodBean javsScriptMethodBean = new JavsScriptMethodBean();
        javsScriptMethodBean.setClassName(className);
        String groupContent = methodContentList.get(0);
        if(groupContent.trim().startsWith(TagConstants.FUNC)){
            groupContent = groupContent.replace("{","").replace(TagConstants.FUNC,"").trim();
            String [] methodParamArr = groupContent.split("\\(");
            javsScriptMethodBean.setMethodName(methodParamArr[0]);
            String methodParam = methodParamArr[1].replace(")","").trim();
            int paramCount = 0;
            if(!StringUtils.isEmpty(methodParam)){
                if(!methodParam.contains(",")){
                    paramCount = 1;
                }else {
                    paramCount = methodParam.split(",").length;
                }
            }
            MethodModel methodModel = javsTranslateContextBean.getByClassMethod(className,methodParamArr[0],paramCount);
            if(methodModel == null){
                javsScriptMethodBean.setMissOriginMethod(true);
                return javsScriptMethodBean;
            }
            String paramStr = methodParamArr[1].replace(")","");
            if(!StringUtils.isEmpty(paramStr)){
                List<JavsParamBean> paramBeanList = new ArrayList<>();
                if(paramStr.contains(",")){
                    String [] javsParamArr = paramStr.split(",");
                    for (int i = 0;i < javsParamArr.length;i ++){
                        methodModel.getParamModelList().get(i);
                        JavsParamBean javsParamBean = javsScriptFactory.buildFromParamModel(methodModel.getParamModelList().get(i),javsParamArr[i]);
                        paramBeanList.add(javsParamBean);
                    }
                }else {
                    JavsParamBean javsParamBean = javsScriptFactory.buildFromParamModel(methodModel.getParamModelList().get(0),paramStr);
                    paramBeanList.add(javsParamBean);
                }
                javsScriptMethodBean.setParamBeanList(paramBeanList);
            }
        }

        javsScriptMethodBean.setJavsShellContentList(Lists.newArrayList(methodContentList));
        return javsScriptMethodBean;
    }


    /**
     * 根据import关键字获取javs脚本中的包导入宏定义内容
     * @param javsRowList
     * @return
     */
    public List<String> getPackageImportRowLine(List<String> javsRowList){
        List<String> packageImportList = Lists.newArrayList();
        for (String row : javsRowList){
            if(StringUtils.isEmpty(row)){
                continue;
            }
            if(row.trim().startsWith(TagConstants.IMPORT)){
                packageImportList.add(row);
            }
        }
        return packageImportList;
    }


    /**
     * 根据import关键字获取javs脚本中的包导入宏定义内容
     * @param javsRowList
     * @return
     */
    public List<String> getFuncRowLine(List<String> javsRowList){
        List<String> funcRowContentList = Lists.newArrayList();
        int firstFuncIndex = 0;
        for (int i = 0;i < javsRowList.size();i ++){
            if(javsRowList.get(i).trim().startsWith("func") && javsRowList.get(i).trim().contains("(")){
                firstFuncIndex = i;
                break;
            }
        }

        if(firstFuncIndex > 0){
            List<String> funcContentList = javsRowList.subList(firstFuncIndex,javsRowList.size() - 1);
            for (String str : funcContentList){
                funcRowContentList.add(str);
            }
        }
        return funcRowContentList;
    }



    /**
     * 根据import关键字获取javs脚本中的包导入宏定义内容
     * @param javsRowList
     * @return
     */
    public List<String> getGlobalFieldRowLine(List<String> javsRowList){
        List<String> globalFieldList = Lists.newArrayList();
        for (String row : javsRowList){
            if(StringUtils.isEmpty(row)){
                continue;
            }

            if(row.trim().startsWith(TagConstants.IMPORT)){
                continue;
            }
            if(row.trim().startsWith(TagConstants.DOC_LINE) || row.trim().startsWith(TagConstants.DOC_JING)){
                continue;
            }
            if(row.trim().startsWith(TagConstants.FUNC)){
                break;
            }
            globalFieldList.add(row);
        }
        return globalFieldList;
    }

    /**
     * 截取参数列表
     * @param param
     * @return
     */
    public  List<String> getParamList(String param){
        int firstIndex = param.indexOf(TagConstants.BRACKET_LEFT);
        int lastIndex = param.lastIndexOf(TagConstants.BRACKET_RIGHT);
        if(lastIndex - firstIndex == 1){
            return Lists.newArrayList();
        }


        if(firstIndex == lastIndex && firstIndex == -1){
            if (param.contains(",")) {
                return Lists.newArrayList(param.split(","));
            }else {
                return Lists.newArrayList(param);
            }
        }

        String paramStr = param.substring(firstIndex + 1,lastIndex);
        if (paramStr.contains(",")) {
            return Lists.newArrayList(paramStr.split(","));
        }else {
            return Lists.newArrayList(paramStr);
        }
    }


    /**
     * 判断是否是静态方法调用
     * @param segment
     * @return
     */
    public boolean checkStaticMethodRefer(String segment){
        //User.xxxx()
        //User(a.xxx,"sdsd")
        int firstIndex = segment.indexOf(".");
        int secondIndex = segment.indexOf("(");
        if((secondIndex > firstIndex) && StringHandleUtils.isUpperFirst(segment.trim())){
            return true;
        }
        return false;
    }

}
